package com.xzw.test.springcloud.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import com.xzw.test.springcloud.model.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.Future;

@Service
@Slf4j
public class HystrixService {

    @Autowired
    RestTemplate resTtemplate;

    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    /**
     * 在这个方法中，我们将发起一个远程调用，去调用 PaymentController 中提供的接口
     *
     * 但是，这个调用可能会失败。
     *
     * 我们在这个方法上添加 @HystrixCommand 注解，配置 fallbackMethod 属性，这个属性表示
     * 该方法调用失败时的临时替代方法
     */
    @HystrixCommand(fallbackMethod = "error")
    public CommonResult getPaymentById(Long id){
        return resTtemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
    }

    /*@HystrixCommand
    public String getName(){
        String result = resTtemplate.getForObject(PAYMENT_URL + "/payment/get/id={id}", String.class,1L);
        return result;
    }*/

    //注解异步执行
    @HystrixCommand
    public Future<String> getName2(){
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                log.info("===getUser2=====");
                //String forObject = resTtemplate.getForObject(PAYMENT_URL + "/api/user?id={}", String.class, 1L);
                String forObject = resTtemplate.getForObject(PAYMENT_URL + "/api/user/1",String.class);
                return forObject;
            }
        };
    }

    @HystrixCommand(fallbackMethod = "error",
            ignoreExceptions = {ArrayIndexOutOfBoundsException.class},
            commandKey = "getUsercommandKey",
            groupKey = "getUsergroupKey",
            threadPoolKey="getUserthreadPoolKey")
    public String getUser(){
        String result = resTtemplate.getForObject(PAYMENT_URL+"/api/user", String.class);
        return result;
    }

    @HystrixCommand(fallbackMethod = "error1")
    public String error(){
        return resTtemplate.getForObject(PAYMENT_URL+"/api/user", String.class);
    }

    public String error1(){
        return "error1";
    }


    /**
     * 测试该方法，需要把提供者服务停掉
     * 注意，这个方法名字要和 fallbackMethod 一致
     * 方法返回值也要和对应的方法一致
     * 和getPaymentById方法，入参必须保持一致
     * @return
     */
    public CommonResult error(Long id){
        log.info("熔断方法接收参数id:{}",id);
        CommonResult commonResult =new CommonResult();
        commonResult.setCode(500);
        commonResult.setMsg("error");

        return commonResult;
    }
}
